package main

import (
	"fmt"
	"math/rand"
	"strconv"
)

type Student struct {
	Name  string
	Age   int
	Score float32
	next  *Student
}

func trans(p *Student) {
	for p != nil {
		fmt.Println(*p)
		p = p.next
	}

	fmt.Println()
}

func insertTail(p *Student) {
	var tail = p
	for i := 0; i < 10; i++ {
		stu := Student{
			Name:  fmt.Sprintf("stu%d", i),
			Age:   rand.Intn(100),
			Score: rand.Float32() * 100,
		}

		tail.next = &stu
		tail = &stu
	}
}

func insertHead(p **Student) []*Student{

	var list []*Student
	//var tail = p
	for i := 0; i < 10; i++ {
		stu := Student{
			Name:  fmt.Sprintf("stu%d", i),
			Age:   rand.Intn(100),
			Score: rand.Float32() * 100,
		}

		list = append(list, &stu)

		stu.next = *p
		*p = &stu
	}

	return list
}

func delNode(p *Student) {

	var prev *Student = p
	for p != nil {
		if p.Name == "stu6" {
			prev.next = p.next
			break
		}
		prev = p
		p = p.next
	}
}

func addNode(p *Student, newNode *Student) {

	for p != nil {
		if p.Name == "stu9" {
			newNode.next = p.next
			p.next = newNode
			break
		}

		p = p.next
	}
}

func steps(n int) int {
	var walkingModeList []int = []int{1, 2, 3}
	total := 0
	sum := 0
	for {

		if n - sum == 1{
			total += 1
			break
		}

		if n - sum == 2{
			total += 1
			break
		}

		if n - sum == 3{
			total += 1
			break
		}

		perStep := rand.Intn(len(walkingModeList))
		sum += perStep

		if sum == n{
			total += 1
			break
		}
	}

	return total
}

func mergeSort(data []int) []int {
	length := len(data)
	if length <= 1 {
		return data
	}
	num := length / 2
	left := mergeSort(data[:num])
	right := mergeSort(data[num:])
	return merge(left, right)
}

func merge(left, right []int) (result []int) {
	l, r := 0, 0
	for l < len(left) && r < len(right) {
		if left[l] < right[r] {
			result = append(result, left[l])
			l++
		} else {
			result = append(result, right[r])
			r++
		}
	}
	result = append(result, left[l:]...)
	result = append(result, right[r:]...)
	return
}

func main() {
	var head *Student = new(Student)

	head.Name = "hua"
	head.Age = 18
	head.Score = 100

	//insertTail(head)
	//trans(head)

	// "hua -> 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8"
	list := insertHead(&head)
	for _, s := range list {
		fmt.Println("Name：", s.next.Name)
	}
	trans(head)

	//delNode(head)
	//trans(head)

	//var newNode *Student = new(Student)
	//
	//newNode.Name = "stu1000"
	//newNode.Age = 18
	//newNode.Score = 100
	//addNode(head, newNode)
	//trans(head)


	var tt *Student = new(Student)
	tt.Name = "旧旧旧"

	var s1 = Student{
		Name:  fmt.Sprintf("stu%d", 100),
		Age:   rand.Intn(100),
		Score: rand.Float32() * 100,
	}
	tt = &s1

	fmt.Println("tt：", tt.Name)

	fmt.Println("一共 " + strconv.Itoa(steps(10)) + " 种走法")

	s := make([]int, 0, 16)
	for i := 0; i < 16; i++ {
		s = append(s, rand.Intn(100))
	}
	fmt.Println(s)
	s = mergeSort(s)
	fmt.Println(s)
}
